local nibMicroMenu = LibStub("AceAddon-3.0"):NewAddon("nibMicroMenu", "AceConsole-3.0", "AceEvent-3.0");
local L = LibStub("AceLocale-3.0"):GetLocale("nibMicroMenu");
local media = LibStub("LibSharedMedia-3.0");

local db;

local defaults = {
	profile = {
		texts = {
			[1] = "C",
			[2] = "S",
			[3] = "T",
			[4] = "A",
			[5] = "Q",
			[6] = "O",
			[7] = "G",
			[8] = "P",
			[9] = "D",
			[10] = "?",
		},
		font = {
			size = 12,
			name = "Friz Quadrata TT",
		},
		position = {
			anchorto = "CENTER",
			anchorfrom = "CENTER",
			parent = "UIParent",
			x = 0,
			y = 0,
			orientation = "Horizontal",
			reversed = false,
		},
		framelevel = {
			automatic = true,
			strata = "MEDIUM",
			level = 2,
		},
		microadjustments = {
			x = 0,
			y = 0,
			width = 0,
			height = 0,
			individual = {
				["**"] = {x = 0, y = 0, width = 0},
			},
		},
		tooltip = {
			enabled = true,
		},
		normal = {
			outline = "NONE",
			shadow = {
				useshadow = true,
				color = {
					r = 0,
					g = 0,
					b = 0,
					a = 1,
				},
				position = {
					x = 1,
					y = -1.
				},
			},
			colors = {
				class = {
					enabled = false,
					shade = 0.70,
				},
				r = 0.70,
				g = 0.70,
				b = 0.70,
			},
			opacity = 1,
		},
		highlight = {
			outline = "NONE",
			shadow = {
				useshadow = true,
				color = {
					r = 0,
					g = 0,
					b = 0,
					a = 1,
				},
				position = {
					x = 1,
					y = -1.
				},
			},
			colors = {
				class = {
					enabled = false,
					shade = 1,
				},
				r = 1,
				g = 1,
				b = 1,
			},
			opacity = 1,
		},
		disabled = {
			outline = "NONE",
			shadow = {
				useshadow = true,
				color = {
					r = 0,
					g = 0,
					b = 0,
					a = 1,
				},
				position = {
					x = 1,
					y = -1.
				},
			},
			colors = {
				class = {
					enabled = false,
					shade = .4,
				},
				r = .4,
				g = .4,
				b = .4,
			},
			opacity = 1,
		},
		combatfader = {
			enabled = false,
			showonmouseover = true,
			opacity = {
				incombat = 1,
				hurt = .7,
				target = .7,
				outofcombat = .3,
			},
		},
	},
};

local NumButtons = 10;

local frameMicroMenu;
local mmbuttons = {
	[1] = {
		id = "character",
		frame = nil,
		highlight = false,
		windowopen = false,
	},
	[2] = {
		id = "spellbook",
		frame = nil,
		highlight = false,
		windowopen = false,
	},
	[3] = {
		id = "talents",
		frame = nil,
		highlight = false,
		windowopen = false,
		disabled = false,
	},
	[4] = {
		id = "achievements",
		frame = nil,
		highlight = false,
		windowopen = false,
		disabled = false,
	},
	[5] = {
		id = "questlog",
		frame = nil,
		highlight = false,
		windowopen = false,
	},
	[6] = {
		id = "social",
		frame = nil,
		highlight = false,
		windowopen = false,
	},
	[7] = {
		id = "guild",
		frame = nil,
		highlight = false,
		windowopen = false,
		disabled = false,
	},
	[8] = {
		id = "pvp",
		frame = nil,
		highlight = false,
		windowopen = false,
		disabled = false,
	},
	[9] = {
		id = "dungeonfinder",
		frame = nil,
		highlight = false,
		windowopen = false,
		disabled = false,
	},
	[10] = {
		id = "helprequest",
		frame = nil,
		highlight = false,
		windowopen = false,
	},
};

local CharID = 1;
local SpellBookID = 2;
local TalentsID = 3;
local AchievementsID = 4;
local QuestLogID = 5;
local SocialID = 6;
local GuildID = 7;
local PvPID = 8;
local LFDID = 9;
local HelpID = 10;

local FadeTime = 0.25;
local status;

-- Power 'Full' check
local power_check = {
	MANA = function()
		return UnitMana("player") < UnitManaMax("player")
	end,
	RAGE = function()
		return UnitMana("player") > 0
	end,
	ENERGY = function()
		return UnitMana("player") < UnitManaMax("player")
	end,
	RUNICPOWER = function()
		return UnitMana("player") > 0
	end,
};

-- Fade frame
local function FadeIt(self, NewOpacity)
	local CurrentOpacity = self:GetAlpha();
	if NewOpacity > CurrentOpacity then
		UIFrameFadeIn(self, FadeTime, CurrentOpacity, NewOpacity);
	elseif NewOpacity < CurrentOpacity then
		UIFrameFadeOut(self, FadeTime, CurrentOpacity, NewOpacity);
	end
end

-- Determine new opacity values for frames
function nibMicroMenu:FadeFrames()
	local NewOpacity;

	-- Retrieve opacity/visibility for current status
	NewOpacity = 1;
	if status == "DISABLED" then
		NewOpacity = 1;
	elseif status == "INCOMBAT" then
		NewOpacity = db.combatfader.opacity.incombat;
	elseif status == "TARGET" then
		NewOpacity = db.combatfader.opacity.target;
	elseif status == "HURT" then
		NewOpacity = db.combatfader.opacity.hurt;
	elseif status == "OUTOFCOMBAT" then
		NewOpacity = db.combatfader.opacity.outofcombat;
	end

	-- Fade Frames
	FadeIt(frameMicroMenu, NewOpacity);
end

function nibMicroMenu:UpdateCFStatus()
	local OldStatus = status;
	
	-- Combat Fader disabled
	if not db.combatfader.enabled then
		status = "DISABLED";
		if status ~= OldStatus then nibMicroMenu:FadeFrames(); end
		return
	end
	
	-- Show on mouse over
	if db.combatfader.showonmouseover then	
		for k,v in pairs(mmbuttons) do
			if mmbuttons[k].highlight then
				status = "DISABLED";
				UIFrameFadeIn(frameMicroMenu, FadeTime, frameMicroMenu:GetAlpha(), 1);
				return
			end
		end
	end
	
	-- Combat Fader based on status
	if UnitAffectingCombat("player") then
		status = "INCOMBAT";
	elseif UnitExists("target") then
		status = "TARGET";
	elseif UnitHealth("player") < UnitHealthMax("player") then
		status = "HURT";
	else
		local _, power_token = UnitPowerType("player");
		local func = power_check[power_token];
		if func and func() then
			status = "HURT";
		else
			status = "OUTOFCOMBAT";
		end
	end
	if status ~= OldStatus then nibMicroMenu:FadeFrames(); end
end

function nibMicroMenu:UpdateCombatFader()
	status = nil;
	nibMicroMenu:UpdateCFStatus();
end

function nibMicroMenu:UpdateCombatFaderEnabled()
	if db.combatfader.enabled then
		self:RegisterEvent("PLAYER_TARGET_CHANGED", "UpdateCFStatus");
		self:RegisterEvent("PLAYER_REGEN_ENABLED", "UpdateCFStatus");
		self:RegisterEvent("PLAYER_REGEN_DISABLED", "UpdateCFStatus");
		self:RegisterEvent("UNIT_HEALTH", "UpdateCFStatus");
		self:RegisterEvent("UNIT_MANA", "UpdateCFStatus");
		self:RegisterEvent("UNIT_RAGE", "UpdateCFStatus");
		self:RegisterEvent("UNIT_ENERGY", "UpdateCFStatus");
		self:RegisterEvent("UNIT_POWER", "UpdateCFStatus");
		self:RegisterEvent("UNIT_RUNIC_POWER", "UpdateCFStatus");
		self:RegisterEvent("UNIT_DISPLAYPOWER", "UpdateCFStatus");
		
		nibMicroMenu:UpdateCombatFader();
		nibMicroMenu:FadeFrames();
	else
		self:UnregisterEvent("PLAYER_TARGET_CHANGED");
		self:UnregisterEvent("PLAYER_REGEN_ENABLED");
		self:UnregisterEvent("PLAYER_REGEN_DISABLED");
		self:UnregisterEvent("UNIT_HEALTH");
		self:UnregisterEvent("UNIT_MANA");
		self:UnregisterEvent("UNIT_RAGE");
		self:UnregisterEvent("UNIT_ENERGY");
		self:UnregisterEvent("UNIT_POWER");
		self:UnregisterEvent("UNIT_RUNIC_POWER");
		self:UnregisterEvent("UNIT_DISPLAYPOWER");
		
		nibMicroMenu:UpdateCombatFader();
		nibMicroMenu:FadeFrames();
	end
end

-- Update Disabled/Pushed state of MM Buttons
local function UpdateButtonState()
	local playerLevel = UnitLevel("player");
	
	-- Character
	if CharacterFrame:IsShown() then
		mmbuttons[CharID].windowopen = true;
	else
		mmbuttons[CharID].windowopen = false;
	end
	
	-- SpellBook
	if SpellBookFrame:IsShown() then
		mmbuttons[SpellBookID].windowopen = true;
	else
		mmbuttons[SpellBookID].windowopen = false;
	end

	-- Talents
	if PlayerTalentFrame and PlayerTalentFrame:IsShown() then
		mmbuttons[TalentsID].windowopen = true;
	else
		if GetNumTalentPoints ~= nil then
			if GetNumTalentPoints() == 0 then
				mmbuttons[TalentsID].disabled = true;
			else
				mmbuttons[TalentsID].disabled = false;
				mmbuttons[TalentsID].windowopen = false;
			end
		else
			mmbuttons[TalentsID].disabled = true;
		end
	end
	
	-- Achievements
	if AchievementFrame and AchievementFrame:IsShown() then
		mmbuttons[AchievementsID].windowopen = true;
	else
		if (HasCompletedAnyAchievement() or IsInGuild()) and CanShowAchievementUI() then
			mmbuttons[AchievementsID].disabled = false;
			mmbuttons[AchievementsID].windowopen = false;			
		else
			mmbuttons[AchievementsID].disabled = true;
		end
	end

	-- QuestLog
	if QuestLogFrame:IsShown() then
		mmbuttons[QuestLogID].windowopen = true;
	else
		mmbuttons[QuestLogID].windowopen = false;
	end
	
	-- Social
	if FriendsFrame:IsShown() then
		mmbuttons[SocialID].windowopen = true;
	else
		mmbuttons[SocialID].windowopen = false;
	end
	
	-- Guild
	if IsInGuild() then
		if (GuildFrame and GuildFrame:IsShown()) then
			mmbuttons[GuildID].windowopen = true;
		else
			mmbuttons[GuildID].disabled = false;
			mmbuttons[GuildID].windowopen = false;
		end
	else
		mmbuttons[GuildID].disabled = true;
	end
	
	-- PvP
	if PVPFrame:IsShown() then
		mmbuttons[PvPID].windowopen = true;
	else
		if playerLevel < PVPMicroButton.minLevel then
			mmbuttons[PvPID].disabled = true;
		else
			mmbuttons[PvPID].disabled = false;
			mmbuttons[PvPID].windowopen = false;
		end
	end	

	-- LFD
	if LFDParentFrame:IsShown() then
		mmbuttons[LFDID].windowopen = true;
	else
		if playerLevel < LFDMicroButton.minLevel then
			mmbuttons[LFDID].disabled = true;
		else
			mmbuttons[LFDID].disabled = false;
			mmbuttons[LFDID].windowopen = false;
		end
	end

	-- Help Request
	if HelpFrame:IsShown() then
		mmbuttons[HelpID].windowopen = true;
	else
		mmbuttons[HelpID].windowopen = false;
	end
	
	-- Update Buttons with new information
	nibMicroMenu:UpdateButtons();
end

-- OnMouseDown
function nibMicroMenu_ButtonClick(button)
	if button == "character" then
		if not mmbuttons[CharID].disabled then
			ToggleCharacter("PaperDollFrame");
		end
	elseif button == "spellbook" then
		if not mmbuttons[SpellBookID].disabled then
			ToggleFrame(SpellBookFrame);
		end
	elseif button == "talents" then
		if not mmbuttons[TalentsID].disabled then
			ToggleTalentFrame();
		end
	elseif button == "achievements" then
		if not mmbuttons[AchievementsID].disabled then
			ToggleAchievementFrame();
		end
	elseif button == "questlog" then
		if not mmbuttons[QuestLogID].disabled then
			ToggleFrame(QuestLogFrame);
		end
	elseif button == "social" then
		if not mmbuttons[SocialID].disabled then
			ToggleFriendsFrame();
		end
	elseif button == "guild" then
		if not mmbuttons[GuildID].disabled then
			ToggleGuildFrame();
		end
	elseif button == "pvp" then
		if not mmbuttons[PvPID].disabled then
			TogglePVPFrame();
		end
	elseif button == "dungeonfinder" then
		if not mmbuttons[LFDID].disabled then
			ToggleLFDParentFrame();
		end
	elseif button == "helprequest" then
		if not mmbuttons[HelpID].disabled then
			ToggleHelpFrame();
		end
	end	
end

-- OnLeave
function nibMicroMenu_ButtonOnLeave(button)
	if button == "character" then
		mmbuttons[CharID].highlight = false;
	elseif button == "spellbook" then
		mmbuttons[SpellBookID].highlight = false;
	elseif button == "talents" then
		mmbuttons[TalentsID].highlight = false;
	elseif button == "achievements" then
		mmbuttons[AchievementsID].highlight = false;
	elseif button == "questlog" then
		mmbuttons[QuestLogID].highlight = false;
	elseif button == "social" then
		mmbuttons[SocialID].highlight = false;
	elseif button == "guild" then
		mmbuttons[GuildID].highlight = false;
	elseif button == "pvp" then
		mmbuttons[PvPID].highlight = false;
	elseif button == "dungeonfinder" then
		mmbuttons[LFDID].highlight = false;
	elseif button == "helprequest" then
		mmbuttons[HelpID].highlight = false;
	end

	if db.tooltip.enabled then
		if GameTooltip:IsShown() then GameTooltip:Hide(); end
	end
	
	nibMicroMenu:UpdateButtons();
	if db.combatfader.showonmouseover then nibMicroMenu:UpdateCFStatus(); end
end

-- OnEnter
function nibMicroMenu_ButtonOnEnter(button)
	local tt, tto = "", nil;
	if button == "character" then
		mmbuttons[CharID].highlight = true;
		tt = MicroButtonTooltipText(CHARACTER_BUTTON, "TOGGLECHARACTER0");
		tto = mmbuttons[CharID].frame;
	elseif button == "spellbook" then
		mmbuttons[SpellBookID].highlight = true;
		tt = MicroButtonTooltipText(SPELLBOOK_ABILITIES_BUTTON, "TOGGLESPELLBOOK");
		tto = mmbuttons[SpellBookID].frame;
	elseif button == "talents" then
		mmbuttons[TalentsID].highlight = true;
		tt = MicroButtonTooltipText(TALENTS_BUTTON, "TOGGLETALENTS");
		tto = mmbuttons[TalentsID].frame;
	elseif button == "achievements" then
		mmbuttons[AchievementsID].highlight = true;
		tt = MicroButtonTooltipText(ACHIEVEMENT_BUTTON, "TOGGLEACHIEVEMENT");
		tto = mmbuttons[AchievementsID].frame;
	elseif button == "questlog" then
		mmbuttons[QuestLogID].highlight = true;
		tt = MicroButtonTooltipText(QUESTLOG_BUTTON, "TOGGLEQUESTLOG");
		tto = mmbuttons[QuestLogID].frame;
	elseif button == "social" then
		mmbuttons[SocialID].highlight = true;
		tt = MicroButtonTooltipText(SOCIAL_BUTTON, "TOGGLESOCIAL");
		tto = mmbuttons[SocialID].frame;
	elseif button == "guild" then
		mmbuttons[GuildID].highlight = true;
		tt = MicroButtonTooltipText(GUILD, "TOGGLEGUILDTAB");
		tto = mmbuttons[GuildID].frame;
	elseif button == "pvp" then
		mmbuttons[PvPID].highlight = true;
		tt = MicroButtonTooltipText(PLAYER_V_PLAYER, "TOGGLECHARACTER4");
		tto = mmbuttons[PvPID].frame;
	elseif button == "dungeonfinder" then
		mmbuttons[LFDID].highlight = true;
		tt = MicroButtonTooltipText(DUNGEONS_BUTTON, "TOGGLELFGPARENT");
		tto = mmbuttons[LFDID].frame;
	elseif button == "helprequest" then
		mmbuttons[HelpID].highlight = true;
		tt = HELP_BUTTON;
		tto = mmbuttons[HelpID].frame;
	end	
	
	if db.tooltip.enabled then
		GameTooltip:SetOwner(tto);
		GameTooltip_AddNewbieTip(tto, tt, 1.0, 1.0, 1.0, "");
		GameTooltip:Show();
	end
	
	nibMicroMenu:UpdateButtons();
	if db.combatfader.showonmouseover then nibMicroMenu:UpdateCFStatus(); end
end

local function RetrieveFont(font)
	font = media:Fetch("font", font);
	if font == nil then font = GameFontNormalSmall:GetFont(); end
	return font
end

-- Update Buttons - Font/Colors(Normal, Highlight, Disabled)
function nibMicroMenu:UpdateButtons()
	local cr, cg, cb;
	local styles = {normal = 1, highlight = 2, disabled = 3,};
	local stylecolors = {
		normal = {r = 0, g = 0, b = 0,},
		highlight = {r = 0, g = 0, b = 0,},
		disabled = {r = 0, g = 0, b = 0,},
	};
	local shadow = {
		colors = {
			normal = {r = 0, g = 0, b = 0, a = 1,},
			highlight = {r = 0, g = 0, b = 0, a = 1,},
			disabled = {r = 0, g = 0, b = 0, a = 1,},
		},
		position = {
			normal = {x = 0, y = 0,},
			highlight = {x = 0, y = 0,},
			disabled = {x = 0, y = 0,},
		},
	};
	
	-- Get Button colors
	local class = select(2, UnitClass("player"));
	local classColors = CUSTOM_CLASS_COLORS and CUSTOM_CLASS_COLORS[class] or RAID_CLASS_COLORS[class]
	cr, cg, cb = classColors.r, classColors.g, classColors.b
	
	for k,v in pairs(styles) do
		-- Text Color
		if db[k].colors.class.enabled then
			local shade = db[k].colors.class.shade;
			stylecolors[k].r = cr * shade; stylecolors[k].g = cg * shade; stylecolors[k].b = cb * shade;
		else
			stylecolors[k].r = db[k].colors.r; stylecolors[k].g = db[k].colors.g; stylecolors[k].b = db[k].colors.b;
		end
		
		-- Shadow Color
		if db[k].shadow.useshadow then
			shadow.colors[k].r, shadow.colors[k].g, shadow.colors[k].b, shadow.colors[k].a = db[k].shadow.color.r, db[k].shadow.color.g, db[k].shadow.color.b, db[k].shadow.color.a; 
			shadow.position[k].x, shadow.position[k].y = db[k].shadow.position.x, db[k].shadow.position.y;
		else
			shadow.colors[k].r, shadow.colors[k].g, shadow.colors[k].b, shadow.colors[k].a = 0, 0, 0, 0;
			shadow.position[k].x, shadow.position[k].y = 0, 0;
		end
	end

	local font = RetrieveFont(db.font.name);	
	for i = 1, NumButtons do
		local newstyle, newcolors, newshadowcolors, newshadowposition
		if not mmbuttons[i].disabled then
			if mmbuttons[i].highlight or mmbuttons[i].windowopen then
				-- Highlight
				newstyle = db.highlight;
				newcolors = stylecolors.highlight;
				newshadowcolors = shadow.colors.highlight;
				newshadowposition = shadow.position.highlight;
			else
				-- Normal
				newstyle = db.normal;
				newcolors = stylecolors.normal;
				newshadowcolors = shadow.colors.normal;
				newshadowposition = shadow.position.normal;
			end
		else	-- Disable
			newstyle = db.disabled;
			newcolors = stylecolors.disabled;
			newshadowcolors = shadow.colors.disabled;
			newshadowposition = shadow.position.disabled;
		end
		if mmbuttons[i].frame ~= nil then
			mmbuttons[i].frame.text:SetFont(font, db.font.size, newstyle.outline);
			mmbuttons[i].frame.text:SetTextColor(newcolors.r, newcolors.g, newcolors.b, newstyle.opacity);
			mmbuttons[i].frame.text:SetShadowColor(newshadowcolors.r, newshadowcolors.g, newshadowcolors.b, newshadowcolors.a);
			mmbuttons[i].frame.text:SetShadowOffset(newshadowposition.x, newshadowposition.y);
		end
	end
end

-- Set Size
function nibMicroMenu:UpdateSize()
	local TWidth, THeight;
	local IsVert, IsRev;
	local Positions = {};
	local ButtonWidth = {};
	local ButtonHeight = {};
		
	if db.position.orientation == "Horizontal" then IsVert = false else IsVert = true end
	IsRev = db.position.reversed;
	
	-- Calculate Total height/width and set Button height/width and Text position
	TWidth = 0; THeight = 0;
	for i = 1, NumButtons do
		local NewWidth, NewHeight, NewXOfs, NewYOfs;
		NewWidth = mmbuttons[i].frame.text:GetWidth() + db.microadjustments.width + db.microadjustments.individual[i].width + 2.75;
		NewHeight = mmbuttons[i].frame.text:GetHeight() + db.microadjustments.height + 1;
		NewXOfs = db.microadjustments.x + db.microadjustments.individual[i].x;
		NewYOfs = db.microadjustments.y + db.microadjustments.individual[i].y;
		
		ButtonWidth[i] = NewWidth;
		TWidth = TWidth + NewWidth;
		
		ButtonHeight[i] = NewHeight;
		THeight = THeight + NewHeight;
		
		mmbuttons[i].frame:SetWidth(NewWidth);
		mmbuttons[i].frame:SetHeight(NewHeight);
		mmbuttons[i].frame.text:SetPoint("CENTER", mmbuttons[i].frame, "CENTER", NewXOfs, NewYOfs);
	end
	
	-- Get max width and height of buttons
	local MaxButtonWidth, MaxButtonHeight = 0, 0;
	for i = 1, NumButtons do
		MaxButtonWidth = max(MaxButtonWidth, ButtonWidth[i]);
		MaxButtonHeight = max(MaxButtonHeight, ButtonHeight[i]);
	end
	
	-- Get total orientation value, and set height/width
	local TVal;
	local CSize = {};
	if IsVert then
		TVal = THeight;	
		CSize = ButtonHeight;
		
		frameMicroMenu:SetWidth(MaxButtonWidth);
		frameMicroMenu:SetHeight(THeight);
	else
		TVal = TWidth;
		CSize = ButtonWidth;
		
		frameMicroMenu:SetWidth(TWidth);
		frameMicroMenu:SetHeight(MaxButtonHeight);		
	end
	
	-- Calculate position of each Button	
	for i = 1, NumButtons do
		local CurPos = 0;

		-- Add up position of each Button in sequence
		if i == 1 then
			CurPos = (CSize[i] / 2) - (TVal / 2);
		else
			for j = 1, i-1 do
				CurPos = CurPos + CSize[j];
			end
			CurPos = CurPos + (CSize[i] / 2) - (TVal / 2);
		end					
		
		-- Found Position of Button
		Positions[i] = CurPos;
	end
	
	-- Reverse or not
	local RevMult = 1;
	if IsRev then RevMult = -1;	end
	
	-- Position each Button
	for i = 1, NumButtons do
		if IsVert then
			XPos = 0;
			YPos = (Positions[i] * RevMult);
		else
			XPos = (Positions[i] * RevMult);
			YPos = 0;
		end
		
		mmbuttons[i].frame:ClearAllPoints();
		mmbuttons[i].frame:SetPoint("CENTER", frameMicroMenu, "CENTER", XPos, YPos);
	end
end

-- Set Position
function nibMicroMenu:UpdatePosition()
	local Parent = _G[db.position.parent];
	if not Parent then Parent = UIParent; end
	
	frameMicroMenu:SetParent(Parent);
	frameMicroMenu:ClearAllPoints();
	frameMicroMenu:SetPoint(db.position.anchorfrom, Parent, db.position.anchorto, db.position.x, db.position.y);
	
	local FS, FL;
	if db.framelevel.automatic then
		FS = Parent:GetFrameStrata();
		FL = Parent:GetFrameLevel() + 1;
	else
		FS = db.framelevel.strata;
		FL = db.framelevel.level;
	end	
	frameMicroMenu:SetFrameStrata(FS);
	frameMicroMenu:SetFrameLevel(FL);
	
	frameMicroMenu:Show();
end

-- Set Texts
function nibMicroMenu:UpdateTexts()
	for i = 1, NumButtons do
		mmbuttons[i].frame.text:SetText(db.texts[i]);
	end
	nibMicroMenu:UpdateButtons();
	nibMicroMenu:UpdateSize();	
end

local function ClassColorsUpdate()
	nibMicroMenu:UpdateButtons();
end

local function HookMMUpdate()
	hooksecurefunc("UpdateMicroButtons", UpdateButtonState);
end

local function GetFrames()
	frameMicroMenu = getglobal("nibMicroMenu_Frame");

	mmbuttons[CharID].frame = getglobal("nibMicroMenu_Button_Character");
	mmbuttons[SpellBookID].frame = getglobal("nibMicroMenu_Button_Spellbook");
	mmbuttons[TalentsID].frame = getglobal("nibMicroMenu_Button_Talents");
	mmbuttons[AchievementsID].frame = getglobal("nibMicroMenu_Button_Achievements");
	mmbuttons[QuestLogID].frame = getglobal("nibMicroMenu_Button_QuestLog");
	mmbuttons[SocialID].frame = getglobal("nibMicroMenu_Button_Social");
	mmbuttons[GuildID].frame = getglobal("nibMicroMenu_Button_Guild");
	mmbuttons[PvPID].frame = getglobal("nibMicroMenu_Button_PvP");
	mmbuttons[LFDID].frame = getglobal("nibMicroMenu_Button_DungeonFinder");
	mmbuttons[HelpID].frame = getglobal("nibMicroMenu_Button_HelpRequest");
end

function nibMicroMenu:ProfChange()
	db = self.db.profile;
	nibMicroMenu:ConfigRefresh();
	nibMicroMenu:Refresh();
end

function nibMicroMenu:Refresh()
	nibMicroMenu:UpdatePosition();
	nibMicroMenu:UpdateTexts();
	
	UpdateButtonState();
	nibMicroMenu:UpdateButtons();
	
	nibMicroMenu:UpdateCombatFaderEnabled();
end

function nibMicroMenu:EventCheck()
	UpdateButtonState();
end

function nibMicroMenu:PLAYER_ENTERING_WORLD()
	nibMicroMenu:EventCheck();
	nibMicroMenu:UpdatePosition();
end

function nibMicroMenu:PLAYER_LOGIN()
	GetFrames();
	HookMMUpdate();
	nibMicroMenu:Refresh();
	
	if CUSTOM_CLASS_COLORS then
		CUSTOM_CLASS_COLORS:RegisterCallback(ClassColorsUpdate);
	end
end

function nibMicroMenu:OnInitialize()
	self.db = LibStub("AceDB-3.0"):New("nibMicroMenuDB", defaults, "Default");
		
	self.db.RegisterCallback(self, "OnProfileChanged", "ProfChange");
	self.db.RegisterCallback(self, "OnProfileCopied", "ProfChange");
	self.db.RegisterCallback(self, "OnProfileReset", "ProfChange");
	
	nibMicroMenu:SetUpOptions();
	
	db = self.db.profile;
	
	self:RegisterEvent("PLAYER_LOGIN");
	self:RegisterEvent("PLAYER_ENTERING_WORLD");
	self:RegisterEvent("PLAYER_LEVEL_UP", "EventCheck");
	self:RegisterEvent("UNIT_LEVEL", "EventCheck");
	self:RegisterEvent("RECEIVED_ACHIEVEMENT_LIST", "EventCheck");
	self:RegisterEvent("ACHIEVEMENT_EARNED", "EventCheck");
	self:RegisterEvent("PLAYER_TALENT_UPDATE", "EventCheck");
end